package com.xidian.zhiancloud.util.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;

import com.xidian.zhiancloud.util.api.DateUtils;
import com.xidian.zhiancloud.util.api.StringUtils;


/**
 * 文件处理工具类
 * 
 * @author lituo
 */
public class FileUtils extends org.apache.commons.io.FileUtils
{
    /** 字符常量：斜杠 {@code '/'} */
    public static final char SLASH = '/';

    /** 字符常量：反斜杠 {@code '\\'} */
    public static final char BACKSLASH = '\\';

    public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
    private static final Logger log = LoggerFactory.getLogger(FileUtils.class);
    /**
     * 输出指定文件的byte数组
     * 
     * @param filePath 文件路径
     * @param os 输出流
     * @return
     */
    public static void writeBytes(String filePath, OutputStream os) throws IOException
    {
        FileInputStream fis = null;
        try
        {
            File file = new File(filePath);
            if (!file.exists())
            {
                throw new FileNotFoundException(filePath);
            }
            fis = new FileInputStream(file);
            byte[] b = new byte[1024];
            int length;
            while ((length = fis.read(b)) > 0)
            {
                os.write(b, 0, length);
            }
        }
        catch (IOException e)
        {
            throw e;
        }
        finally
        {
            if (os != null)
            {
                try
                {
                    os.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
            if (fis != null)
            {
                try
                {
                    fis.close();
                }
                catch (IOException e1)
                {
                    e1.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除文件
     * 
     * @param filePath 文件
     * @return
     */
    public static boolean deleteFile(String filePath)
    {
        boolean flag = false;
        File file = new File(filePath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists())
        {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 文件名称验证
     * 
     * @param filename 文件名称
     * @return true 正常 false 非法
     */
    public static boolean isValidFilename(String filename)
    {
        return filename.matches(FILENAME_PATTERN);
    }

    /**
     * 检查文件是否可下载
     * 
     * @param resource 需要下载的文件
     * @return true 正常 false 非法
     */
    public static boolean checkAllowDownload(String resource)
    {
        // 禁止目录上跳级别
        if (StringUtils.contains(resource, ".."))
        {
            return false;
        }

        // 检查允许下载的文件规则
        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
        {
            return true;
        }

        // 不在允许下载的文件规则
        return false;
    }

    /**
     * 下载文件名重新编码
     * 
     * @param request 请求对象
     * @param fileName 文件名
     * @return 编码后的文件名
     */
    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
    {
        final String agent = request.getHeader("USER-AGENT");
        String filename = fileName;
        if (agent.contains("MSIE"))
        {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        }
        else if (agent.contains("Firefox"))
        {
            // 火狐浏览器
            filename = new String(fileName.getBytes(), "ISO8859-1");
        }
        else if (agent.contains("Chrome"))
        {
            // google浏览器
        	fileName = new String(fileName.getBytes("utf-8"), "ISO8859-1");
        }
        else
        {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }

    /**
     * 返回文件名
     *
     * @param filePath 文件
     * @return 文件名
     */
    public static String getName(String filePath)
    {
        if (null == filePath)
        {
            return null;
        }
        int len = filePath.length();
        if (0 == len)
        {
            return filePath;
        }
        if (isFileSeparator(filePath.charAt(len - 1)))
        {
            // 以分隔符结尾的去掉结尾分隔符
            len--;
        }

        int begin = 0;
        char c;
        for (int i = len - 1; i > -1; i--)
        {
            c = filePath.charAt(i);
            if (isFileSeparator(c))
            {
                // 查找最后一个路径分隔符（/或者\）
                begin = i + 1;
                break;
            }
        }

        return filePath.substring(begin, len);
    }

    /**
     * 是否为Windows或者Linux（Unix）文件分隔符<br>
     * Windows平台下分隔符为\，Linux（Unix）为/
     *
     * @param c 字符
     * @return 是否为Windows或者Linux（Unix）文件分隔符
     */
    public static boolean isFileSeparator(char c)
    {
        return SLASH == c || BACKSLASH == c;
    }
    
    
    
    /**
     *  文件转移
     * @param startFile
     * @param endDirection
     */
    public static void moveFolder(File startFile,File endDirection)
    {
    	//如果目的目录路径不存在，则进行创建
    	if(!endDirection.exists()) {
    	   endDirection.mkdirs();
    	}

    	//目的文件路径=目的目录路径+源文件名称
    	File endFile=new File(endDirection+ File.separator+ startFile.getName());

    	try {
    		//调用File类的核心方法renameTo
    		if (startFile.renameTo(endFile)) {
    		   System.out.println("文件移动成功！目标路径：{"+endFile.getAbsolutePath()+"}");
    		} else {
    		   System.out.println("文件移动失败！起始路径：{"+startFile.getAbsolutePath()+"}");
    		}			
    	}catch(Exception e) {
    		System.out.println("文件移动出现异常！起始路径：{"+startFile.getAbsolutePath()+"}");		
    	}			
    
    }

    /**
     * 下载文件名重新编码
     *
     * @param response 响应对象
     * @param realFileName 真实文件名
     * @return
     */
    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
    {
        String percentEncodedFileName = percentEncode(realFileName);

        StringBuilder contentDispositionValue = new StringBuilder();
        contentDispositionValue.append("attachment; filename=")
                .append(percentEncodedFileName)
                .append(";")
                .append("filename*=")
                .append("utf-8''")
                .append(percentEncodedFileName);

        response.setHeader("Content-disposition", contentDispositionValue.toString());
    }
    
    
    public static void download(HttpServletResponse resp, HttpServletRequest req,String path,String root) throws IOException {
    	String fileName = getName(path);
    	if(!isValidFilename(fileName)) {
    		 throw new RuntimeException("文件类型有误");
    	}
    	fileName = setFileDownloadHeader(req,fileName);
    	setAttachmentResponseHeader(resp,fileName);
    	writeBytes(root,resp.getOutputStream());
    	
    }
    
    
    
    

    /**
     * 百分号编码工具方法
     *
     * @param s 需要百分号编码的字符串
     * @return 百分号编码后的字符串
     */
    public static String percentEncode(String s) throws UnsupportedEncodingException
    {
        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
        return encode.replaceAll("\\+", "%20");
    }
public static  String uploadFile(MultipartFile mFile ,String file_path,String type) {
    	
    	//Map<String, String> map = new HashMap<>();
        File targetFile = null;
        String returnUrl="";
        if (mFile != null) {
 
            String fileName = mFile.getOriginalFilename();//获取文件名加后缀
            //文件原名称
            //map.put("original", fileName);
            if (fileName != null && fileName != "") {
                //String last = fileName.substring(fileName.lastIndexOf("."), fileName.length());//文件后缀
                //文件类型 .+后缀名
                //map.put("type", last);
                //文件大小（字节数）
                //map.put("size", mFile.getSize() + "");
 
                //String newName = new Date().getTime() + new Random().nextInt(1000) + last;//新的文件名
 
                //先判断文件是否存在
                String fileAdd = DateUtils.dateTimeNow(DateUtils.YYYY_MM_DD);
                File file1 = new File(file_path + "/"+ type + "/" + fileAdd);
                //如果文件夹不存在则创建
                if (!file1.exists() && !file1.isDirectory()) {
                    file1.mkdirs();
                }
                targetFile = new File(file1, fileName);
                try {
                    mFile.transferTo(targetFile);
                    String url = "/" + type + "/" + fileAdd + "/" + fileName;
                    returnUrl =url;
                    //map.put("state", "SUCCESS");
                    //现在文件名称
                    //map.put("title", newName);
                    //文件路径
                    //map.put("url", url);
 
                } catch (IllegalStateException e) {
                	log.error("文件上传失败，参数异常：" + e);
                } catch (IOException e1) {
                    log.error("文件上传失败io异常：" + e1);
                }
            }
        }
 
        return returnUrl;
    	
    }

	public static void main(String[] args) {
			System.out.println(isValidFilename("51246265-ba03-4a6b-9d73-a1920b566c45.png"));
		
	}
}
